package ln.fxspringarchetype.controller.score;

import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.util.StringConverter;
import javafx.util.converter.NumberStringConverter;
import ln.fxspringarchetype.controller.BaseFxController;
import ln.fxspringarchetype.model.Course;
import ln.fxspringarchetype.model.Score;
import ln.fxspringarchetype.model.Student;
import ln.fxspringarchetype.vo.ScoreVO;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public class EditScoreController extends BaseFxController {
    private final ScoreVO scoreVO = new ScoreVO();
    @FXML
    private Label idLabel;
    @FXML
    private ChoiceBox<Student> studentNameBox;
    @FXML
    private ChoiceBox<Course> courseNameBox;
    @FXML
    private DatePicker examDateField;
    @FXML
    private TextField scoreField;

    public ScoreVO getScoreVO() {
        return scoreVO;
    }

    @Override
    public void initLayout() {

    }

    @Override
    public void loadData() {

    }

    @Override
    public void setCellValueFactories() {
        studentNameBox.setConverter(new StringConverter<>() {
            @Override
            public String toString(Student student) {
                return student.getName();
            }

            @Override
            public Student fromString(String studentName) {
                return studentNameBox.getSelectionModel().getSelectedItem();
            }
        });

        courseNameBox.setConverter(new StringConverter<>() {
            @Override
            public String toString(Course course) {
                return course.getName();
            }

            @Override
            public Course fromString(String string) {
                return courseNameBox.getSelectionModel().getSelectedItem();
            }
        });
    }

    @Override
    public void setCellFactories() {

    }

    @Override
    public void createBindings() {
        //绑定记录号
        idLabel.textProperty().bind(
                Bindings.createStringBinding(
                        () -> Integer.toString(scoreVO.getRecordId()), scoreVO.recordIdProperty()));
        //绑定考试日期
        examDateField.valueProperty().bindBidirectional(scoreVO.examDateProperty());
        //绑定得分
        Bindings.bindBidirectional(scoreField.textProperty(), scoreVO.scoreProperty(), new NumberStringConverter());
        //VO中的Student随下拉列表对象而变化
        scoreVO.studentProperty().bind(studentNameBox.getSelectionModel().selectedItemProperty());
        //VO中的Course随下拉对表对象而变化
        scoreVO.courseProperty().bind(courseNameBox.getSelectionModel().selectedItemProperty());
    }

    public void loadListData(List<Student> students, List<Course> courses) {
        studentNameBox.setItems(FXCollections.observableList(FXCollections.observableList(students)));
        courseNameBox.setItems(FXCollections.observableList(FXCollections.observableList(courses)));
    }

    /**
     * 把score实体类转换成ScoreVO
     * 因为ScoreVO的字段绑定了列表，所以不能直接修改，要操纵下拉列表自动选中匹配项
     *
     * @param score 选课成绩实体
     */
    public void loadScore(Score score) {
        scoreVO.fromModelSimple(score);
        //自动在下拉列表中选择与score中的student相匹配的项
        SingleSelectionModel<Student> studentSelectionModel = studentNameBox.getSelectionModel();
        if (studentNameBox.getItems().isEmpty() || Objects.isNull(score.getStudent())) {
            studentSelectionModel.clearSelection();
        } else {
            Student currentStudent = score.getStudent();
            List<Student> matchedStudents = studentNameBox.getItems()
                    .stream()
                    .filter(student -> student.getId() == currentStudent.getId())
                    .collect(Collectors.toList());
            if (matchedStudents.isEmpty()) {
                studentSelectionModel.clearSelection();
                return;
            }
            studentSelectionModel.select(matchedStudents.get(0));
        }

        SingleSelectionModel<Course> courseSelectionModel = courseNameBox.getSelectionModel();
        if (courseNameBox.getItems().isEmpty() || Objects.isNull(score.getCourse())) {
            courseSelectionModel.clearSelection();
        } else {
            Course currentCourse = score.getCourse();
            List<Course> matchedCourses = courseNameBox.getItems()
                    .stream()
                    .filter(course -> course.getId() == currentCourse.getId())
                    .collect(Collectors.toList());
            if (matchedCourses.isEmpty()) {
                courseSelectionModel.clearSelection();
                return;
            }
            courseSelectionModel.select(matchedCourses.get(0));
        }
    }
}
